require("dotenv").config();

const {
  GITEE_CLIENT_ID,
  GITEE_CLIENT_SECRET,
  PORT = 4000,
  SESSION_SECRET,
} = process.env;

const express = require("express");
const session = require("express-session");
const grant = require("grant-express");
const open = require("open");
const { createProxyMiddleware } = require("http-proxy-middleware");
const { createTerminus } = require("@godaddy/terminus");
const init = require("./init");
const graphql = require("./graphql");
const { newClient, connect } = require("./db");
const { initializeCollections } = require("./dao");

const SERVER_HOST = `http://localhost${+PORT === 80 ? "" : ":" + PORT}`;
const CALLBCK_ROUTE = `/initialize`;
const GRAPHQL_ROUTE = `/graphql`;

const mongoClient = newClient();
const app = express();

(async () => {
  // Configurate session for redirect workflow
  app.use(
    session({ secret: SESSION_SECRET, saveUninitialized: true, resave: false })
  );

  // Configurate grant for gitee
  app.use(
    grant({
      defaults: {
        origin: SERVER_HOST,
        transport: "session",
        state: true,
      },
      gitee: {
        authorize_url: `https://gitee.com/oauth/authorize`,
        access_url: `https://gitee.com/oauth/token`,
        key: GITEE_CLIENT_ID,
        secret: GITEE_CLIENT_SECRET,
        oauth: 2,
        custom_params: { response_type: "code" },
        callback: CALLBCK_ROUTE,
      },
    })
  );

  const db = await connect(mongoClient);

  await initializeCollections(db);

  // Initiliaze enterprises
  app.get(CALLBCK_ROUTE, async (req, res) => {
    init(req.session, db);
    res.redirect("/initializing");
  });

  // Enable graphql api
  app.use(GRAPHQL_ROUTE, graphql(db));

  // Proxy static entry to create-react-app
  app.use(
    "/",
    createProxyMiddleware({
      target: "http://localhost:3000",
      changeOrigin: true,
    })
  );

  /*
app.get("/*", function (req, res) {
  res.sendFile(path.join(__dirname, "build", "index.html"));
});
*/

  // Start yagc server
  const server = app.listen(PORT, async () => {
    console.log(
      `Yagc server listening at ${SERVER_HOST}, graphql api on ${SERVER_HOST}${GRAPHQL_ROUTE}`
    );
    const openApp = ["google chrome", "--incognito"];
    await open(`${SERVER_HOST}/connect/gitee`, {
      app: openApp,
    });
    await open(`${SERVER_HOST}${GRAPHQL_ROUTE}`, {
      app: openApp,
    });
  });

  function onSignal() {
    console.log("Server is starting cleanup");
    // start cleanup of resource, like databases or file descriptors
    mongoClient.close();
    console.log("Server cleanup done!");
  }

  async function onHealthCheck() {
    // checks if the system is healthy, like the db connection is live
    // resolves, if health, rejects if not
  }

  createTerminus(server, {
    signal: "SIGINT",
    healthChecks: { "/healthcheck": onHealthCheck },
    onSignal,
  });
})();
